package com.elasticsearch.test;

import java.io.IOException;
import java.util.Map;

import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.highlight.HighlightField;

/**
 * 
 * es客户端连接
 * 
 * @author oyhk
 * 
 */
public class ESClient {

	// @Test
	public static void search(String q) {

		// 创建查询索引
		SearchRequestBuilder searchRequestBuilder = client
				.prepareSearch("medcl");
		// 设置查询索引类型
		searchRequestBuilder.setTypes("news");
		// 设置查询类型
		// 1.SearchType.DFS_QUERY_THEN_FETCH = 精确查询
		// 2.SearchType.SCAN = 扫描查询,无序
		// 3.SearchType.COUNT = 不设置的话,这个为默认值,还有的自己去试试吧
		searchRequestBuilder.setSearchType(SearchType.DFS_QUERY_THEN_FETCH);
		// 设置查询关键词
		// fieldQuery 这个必须是你的索引字段哦,不然查不到数据,这里我只设置两个字段 id ,title
		searchRequestBuilder.setQuery(QueryBuilders.matchQuery("title", q));
		
	
		
	    //QueryBuilder qb1 = termQuery("note", noteParam);

        //qb2构造了一个组合查询（BoolQuery），其对应lucene本身的BooleanQuery，可以通过must、should、mustNot方法对QueryBuilder进行组合，形成多条件查询
        /*QueryBuilder qb2 = boolQuery()
                            .must(termQuery("note", "test1"))
                            .must(termQuery("note", "test4"))
                            .mustNot(termQuery("note", "test2"))
                            .should(termQuery("note", "test3"));*/
         //qb3构造了一个过滤查询，就是在TermQuery的基础上添加一个过滤条件RangeFilter，这个范围过滤器将限制查询age字段大于等于23，小于等于54的结果
        /* QueryBuilder qb3 = filteredQuery(
                         termQuery("note.first", "shay"),
                         rangeFilter("create_date")
                        .from(new Date("2010-02-01"))
                        .to(new Date("2013-03-01"))
                        .includeLower(true)
                        .includeUpper(false)
          );*/
	    
		// 设置查询数据的位置,分页用吧
		searchRequestBuilder.setFrom(0);
		// 设置查询结果集的最大条数
		searchRequestBuilder.setSize(10);
		// 设置是否按查询匹配度排序
		searchRequestBuilder.setExplain(true);

		searchRequestBuilder.addHighlightedField("title");
		// 最后就是返回搜索响应信息
		SearchResponse response = searchRequestBuilder.execute().actionGet();
		
		  // 命中记录数
        Long hitCount = response.getHits().totalHits();
        
        System.out.println("命中总数："+hitCount);

		SearchHits searchHits = response.getHits();
		SearchHit[] hits = searchHits.getHits();
		for (int i = 0; i < hits.length; i++) {
			SearchHit hit = hits[i];

			String id=(String) hit.getSource().get("id");
			System.out.println("id:"+id);
			Map<String, HighlightField> result = hit.highlightFields();
			System.out.println("A map of highlighted fields:" + result);
			HighlightField titleField = result.get("title");
			Text[] titleTexts = titleField.fragments();
			for (Text text : titleTexts) {
				System.out.println("title text: " + text);
			}

			// Map result = hit.getSource();
			// System.out.println(result);
		}
		System.out.println("search success ..");

	}

	public static void main(String[] args) {
		initESClient();
		createIndex();
		search("ab");
		closeESClient();
	}

	/**
	 * 创建索引
	 */

	public static void createIndex() {

		for (int i = 11; i < 1000; i++) {
			String id = "id" + i;
			String title = "中国到底是abc否是发到舒服点诗圣杜甫" + i;
			client.prepareIndex("blog", "post")
					.setSource(getBuilderJson(id, title)).execute().actionGet();
		}

		// BulkRequestBuilder bulkRequest = client.prepareBulk();
		// for(int i=500;i<1000;i++){
		// String id = "id" + i;
		// String title = "this is title" + i;
		// //业务对象
		// String json = getBuilderJson(id, title);
		// IndexRequestBuilder indexRequest = client.prepareIndex("twitter",
		// "tweet")
		// //指定不重复的ID
		// .setSource(json).setId(String.valueOf(i));
		// //添加到builder中
		// bulkRequest.add(indexRequest);
		// }
		//
		// BulkResponse bulkResponse = bulkRequest.execute().actionGet();
		// if (bulkResponse.hasFailures()) {
		// // process failures by iterating through each bulk response item
		// System.out.println(bulkResponse.buildFailureMessage());
		// }
	}

	/**
	 * 创建索引 通常是json格式
	 * 
	 * @param obj
	 *            创建索引的实体
	 * 
	 * @return
	 */
	private static String getBuilderJson(String id, String title) {
		String json = "";
		try {
			XContentBuilder contentBuilder = XContentFactory.jsonBuilder()
					.startObject();
			contentBuilder.field("id", id);
			contentBuilder.field("title", title);
			json = contentBuilder.endObject().string();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return json;
	}

	/**
	 * 初始化客户端连接
	 */
	// @Before
	public static void initESClient() {
		// 配置你的es,现在这里只配置了集群的名,默认是elasticsearch,跟服务器的相同
		Settings settings = ImmutableSettings.settingsBuilder()
				.put("cluster.name", "elasticsearch").build();
		// 这里可以同时连接集群的服务器,可以多个,并且连接服务是可访问的
		client = new TransportClient(settings).addTransportAddresses(
				new InetSocketTransportAddress("127.0.0.1", 9300));
	}

	// @After
	public static void closeESClient() {
		client.close();
	}

	private static Client client;
}